﻿using System;
using System.Collections.Generic;
using System.Threading;

using HtmlAgilityPack;

using SSTU.Contract.Common;
using SSTU.Contract.Facade;
using SSTU.Model;

namespace SSTU.Facade
{
	public class StructureFacade : FacadeBase, IStructureFacade
	{
		/// <summary>
		/// Loads the faculties asynchronously and invoke callback.
		/// </summary>
		/// <param name="asyncCallback">The asynchronous callback.</param>
		public void LoadFacultiesAsync(FacadeAsyncCallback<IEnumerable<Faculty>> asyncCallback)
		{
			var syncContext = SynchronizationContext.Current;
			ThreadPool.QueueUserWorkItem(state =>
			{
				var departments = new Faculty[]
				{
					new Faculty("01", "АМФ", "Автомеханический факультет"),
					new Faculty("08", "ФУПС", "Факультет управления производственными системами"),
					new Faculty("16", "САДИ", "Cтроительно-архитектурно-дорожный институт"),
					new Faculty("07", "ФУСС", "Факультет управления социальными системами"),
					new Faculty("03", "МФ", "Машиностроительный факультет"),
					new Faculty("11", "МФПИТ", "Международный факультет прикладных информационных технологий"),
					new Faculty("05", "ФЭТиП", "Факультет электронной техники и приборостроения"),
					new Faculty("06", "ЭФ", "Энергетический факультет"),
					new Faculty("17", "ФТФ", "Физико-технический факультет"),
					new Faculty("13", "СГФ", "Социально-гуманитарный факультет"),
				};
				var response = new FacadeResponse<IEnumerable<Faculty>>(departments, FacadeResponseDataSource.Server);
				syncContext.Post(@null => asyncCallback(response), null);
			});
		}

		/// <summary>
		/// Loads the groups, by faculty identifier, asynchronously and invoke callback.
		/// </summary>
		/// <param name="facultyId">The faculty identifier.</param>
		/// <param name="asyncCallback">The asynchronous callback.</param>
		public void LoadGroupsAsync(string facultyId, FacadeAsyncCallback<IEnumerable<Group>> asyncCallback)
		{
			var syncContext = SynchronizationContext.Current;
			ThreadPool.QueueUserWorkItem(state =>
			{
				string requestUriPattern = @"http://rasp.sstu.ru/SelSpec.aspx?FAK={0}&OLD=0";
				string requestUriString = string.Format(requestUriPattern, facultyId);
				HtmlWeb.LoadAsync(requestUriString, (o, e) =>
				{
					var response = Do<IEnumerable<Group>>(FacadeResponseDataSource.Server, () =>
					{
						var groups = new List<Group>();
						var allLinks = e.Document.DocumentNode.SelectNodes(@"//a[@href]");
						if (allLinks != null)
						{
							foreach (var link in allLinks)
							{
								//Пример href: http://rasp.sstu.ru/htmlViewRaspBook.aspx?GROUP=91258&OLD=00
								string hrefAttributeValue = link.GetAttributeValue("href", string.Empty);
								if (!string.IsNullOrEmpty(hrefAttributeValue))
								{
									string groupId = hrefAttributeValue.Substring(28, 5);
									if (!string.IsNullOrEmpty(groupId))
									{
										string groupShortName = link.InnerHtml.Trim();
										if (!string.IsNullOrEmpty(groupShortName))
										{
											var group = new Group(groupId, groupShortName, groupShortName);
											groups.Add(group);
										}
									}
								}
							}
						}
						return groups;
					});
					syncContext.Post(responseObject => asyncCallback((FacadeResponse<IEnumerable<Group>>)responseObject), response);
				});
			});
		}

		/// <summary>
		/// Adds the group, by identifier, to favorites asynchronously and invoke callback.
		/// </summary>
		/// <param name="groupId">The group identifier.</param>
		/// <param name="asyncCallback">The async callback.</param>
		public void AddGroupToFavoritesAsync(string groupId, FacadeAsyncCallback asyncCallback)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Removes the group, by identifier, from favorites asynchronously and invoke callback.
		/// </summary>
		/// <param name="groupId">The group identifier.</param>
		/// <param name="asyncCallback">The async callback.</param>
		public void RemoveGroupFromFavoritesAsync(string groupId, FacadeAsyncCallback asyncCallback)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Loads the favorite groups asynchronously and invoke callback.
		/// </summary>
		/// <param name="asyncCallback">The async callback.</param>
		public void LoadFavoriteGroupsAsync(FacadeAsyncCallback<IEnumerable<Group>> asyncCallback)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Loads the group, by identifier, asynchronously and invoke callback.
		/// </summary>
		/// <param name="groupId">The group identifier.</param>
		/// <param name="asyncCallback">The asynchronous callback.</param>
		public void LoadGroupAsync(string groupId, FacadeAsyncCallback<Group> asyncCallback)
		{
			throw new NotImplementedException();
		}
	}
}
